﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Reflection;
using System.Text;
using DataTransmit;
using DataReceive;
using System.IO;



/// <summary>
/// 消费交易
/// </summary>
public partial class PURivr : System.Web.UI.Page
{
    public  string masUrl = ConfigurationManager.AppSettings["masUrl"].ToString();//从配置文件获取MAS服务器地址
    public string tr3Url = ConfigurationManager.AppSettings["tr3Url"].ToString();//从配置文件获取tr3地址:tr3Url，如果指定此地址则会覆盖MAS系统配置的tr3地址
    public string MerchantId = ConfigurationManager.AppSettings["merchantId"].ToString();//从配置文件获取商户号:merchantId
    public string MerchantPw = ConfigurationManager.AppSettings["MerchantPw"].ToString();//从配置文件获取商户密码:MerchantPw
    public string terminalId = ConfigurationManager.AppSettings["terminalId"].ToString();//从配置文件获取终端号:terminalId
    public string prikey_path = HttpContext.Current.Server.MapPath("Certificates") + "\\" + ConfigurationManager.AppSettings["prikey_path"].ToString();//从配置文件获取证书路径:prikey_path
    public string prikey_password = ConfigurationManager.AppSettings["prikey_password"].ToString();//从配置文件获取证书密码: prikey_password
   
    public string txnType = "";//交易类型（PUR表示消费类型）
    public string SettleMerchantId = "";//结算账户
    public string CustomerId = "";//客户号
    public string InteractiveStatus = "";//消息状态
    public string cNo = "";//卡号
    public string eDate = "";//卡有效期
    public string cv2 = "";//卡验证码（CVV2）卡背面3位CVV2数字
    public string amt = "";//金额
    public string cHolderName = "";//持卡人姓名
    public string cHolderId = "";//持卡人身份证号
    public string pValue= "";//扩展数据
    public string eRefNumber = "";//外部跟踪编号：商家订单号

    public string msgReturn = "";//返回数据
    public string responseCode = "";//返回应答码
    public string externalRefNumberback = "";//返回外部跟踪编号
    public string refNumberback = "";//返回系统参考号
    public string authorizationCodeback = "";//返回授权码

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.pnlInfo.Visible = false;
            this.txtCusName.Text = "测试人"; //客户姓名
            this.txtCardHolderName.Text = "测试人";	//持卡人姓名
            this.txtCardHolderId.Text = "130928198310000004";	//持卡人身份证号
            this.txtProductName.Text = "商品名称";	//商品名称
            this.txtAmount.Text = "10";	//订单金额
            this.txtCvv2.Text = "123";	//卡验证码（CVV2）卡背面3位CVV2数字
            this.txtExpriedDate.Text = "0312";	//卡有效期
            this.txtCardNo.Text = "4380880000000007";	//卡号  建行（非直线：提交数据后在tr2返回交易正在处理中，人工处理完，在tr3返回支付结果）：5528010000000001 | 中国银行（直线：提交数据后在tr2返回支付结果）：4380880000000007
            this.txtOrderNo.Text = "PUR-" + DateTime.Now.ToString("yyyyMMddHHmmss");	//商家订单号
            this.txtCellphone.Text = "13716231645";
            this.txtTxnType.Text = "PUR";//交易类型（PUR表示消费类型）
            this.txtSettleMerchantId.Text = "";//结算账户
            this.txtCustomerId.Text = "";//客户号
            this.txtInteractiveStatus.Text = "TR1";//消息状态
            this.txtMerchantId.Text = MerchantId;
            this.txtTerminalId.Text = terminalId;//终端号
            this.txttr3Url.Text = tr3Url;//tr3通知地址

        }
    }


  
    protected void btnOK_Click(object sender, EventArgs e)
    {
        try
        {
            KQMsg Msg = new KQMsg();
            txnType = this.txtTxnType.Text;
            SettleMerchantId = this.txtSettleMerchantId.Text;
            CustomerId = this.txtCustomerId.Text;
            cHolderId = this.txtCardHolderId.Text;
            InteractiveStatus = this.txtInteractiveStatus.Text;
            amt = this.txtAmount.Text;
            cHolderName = this.txtCardHolderName.Text;
            cNo = this.txtCardNo.Text;
            cv2 = this.txtCvv2.Text;
            eDate = this.txtExpriedDate.Text;
            eRefNumber = this.txtOrderNo.Text;
            pValue = this.txtCellphone.Text;
            string eTime = DateTime.Now.ToString("yyyyMMddHHmmss");//获取客户端交易时间

            KuaiQianHelper kq = new KuaiQianHelper();

            //拼接xml
            StringBuilder reqXml = null;
            reqXml = kq.appendParam(reqXml, "version", "1.0");
            reqXml = kq.appendParam(reqXml, "txnType", txnType);//交易类型
            reqXml = kq.appendParam(reqXml, "interactiveStatus", InteractiveStatus);//消息状态
            reqXml = kq.appendParam(reqXml, "cardNo", cNo);//卡号
            reqXml = kq.appendParam(reqXml, "expiredDate", eDate);//有效期
            reqXml = kq.appendParam(reqXml, "cvv2", cv2);//卡验证码（CVV2）卡背面3位CVV2数字
            reqXml = kq.appendParam(reqXml, "amount", amt);//交易金额
            reqXml = kq.appendParam(reqXml, "merchantId", MerchantId);//商户编号
            reqXml = kq.appendParam(reqXml, "settleMerchantId", SettleMerchantId);//结算商户编号：如果有子结算帐号，则要传子帐户编号,没有则不传该节点
            reqXml = kq.appendParam(reqXml, "terminalId", terminalId);//终端号
            reqXml = kq.appendParam(reqXml, "entryTime", eTime);//客户端交易时间
            reqXml = kq.appendParam(reqXml, "externalRefNumber", eRefNumber);//外部跟踪编号：商家订单号
            reqXml = kq.appendParam(reqXml, "customerId", CustomerId);//客户号
            reqXml = kq.appendParam(reqXml, "cardHolderName", cHolderName);//持卡人姓名
            reqXml = kq.appendParam(reqXml, "cardHolderId", cHolderId);//持卡人身份证号
            reqXml = kq.appendParam(reqXml, "tr3", tr3Url);//tr3地址：非直线银行会将支付结果通知到该地址
            reqXml = kq.appendParam(reqXml, "spFlag", "IVR");//特殊交易标志。IVR是手机ivr支付标志

            /*车辆平台测试用：
             * ///错误代码 M4：找不到车辆平台商户
            ///错误代码 M3：保险公司与车辆平台金额不匹配
            ///错误代码 M2：无法找到车保交易信息
            reqXml = kq.appendParam(reqXml, "spFlag", "TOP");//特殊交易标志:车保项目（spFlag=TOP），交易金额会与车辆平台查询的金额进行比较，如果不相同，拒绝交易。
            reqXml = kq.appendParam(reqXml, "ext", "testdata001");//扩展字段：车保填写交易号，即车辆平台查询号
            reqXml = kq.appendParam(reqXml, "ext1", "104110045112103"); 	//扩展字段1：车保填写平台快钱商户号
             //车辆平台测试用结束
             */

            //子节点的拼接
            StringBuilder value = null;
            StringBuilder extdate = null;
            StringBuilder extmap = null;
            StringBuilder key = null;


            value = kq.appendParam(value, "value", pValue, false);//其他信息
            key = kq.appendParam(key, "key", "cellphone" , false);//支付人手机号码
            extdate = kq.appendParam(extdate, "extDate", key.ToString() + value.ToString(), false);
            extmap = kq.appendParam(reqXml, "extMap", extdate.ToString());
                    
            reqXml = kq.appendParam(reqXml, "", "");    
            //
            //商家在此处可以生成订单数据存入数据库，将商品名称，支付人名称，订单金额，订单号，卡号（略缩卡号前六位后四位，不能记录用户完整卡号、有效期、卡验证码（CVV2）信息）
            //

            ////商家一定要添加日志，商家以自己的方式添加日志，以下写XML只做临时测试用
            ////******特别注意：以下部分为:将发送的TR1数据存入文件(xml\send\),调试完要把该出代码删除，以免正式上线后生成很多垃圾文件，******************
            string tr1Return = reqXml.ToString().Replace(" xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\"", "");
            string logPathtr1 = HttpContext.Current.Request.PhysicalApplicationPath + "xml\\send\\" + eRefNumber.Trim() + "_TR1PURSend.xml";
            XmlDocument xmlResponsetr1 = new XmlDocument();
            xmlResponsetr1.LoadXml(tr1Return);
            xmlResponsetr1.Save(logPathtr1);
            ////******写入文件结束******************

            string gatewayUrl = masUrl+"cnp/purchase";//消费网关地址
            //reqXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><MasMessage xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\"><version>1.0</version><TxnMsgContent><txnType>PUR</txnType><interactiveStatus>TR1</interactiveStatus><cardNo>4380880000000007</cardNo><expiredDate>0911</expiredDate><cvv2>111</cvv2><amount>4410</amount><merchantId>999110011220202</merchantId><terminalId>00000202</terminalId><entryTime>20100302140543</entryTime><externalRefNumber>00014602</externalRefNumber><cardHolderId>02020</cardHolderId><tr3Url>http://devtr.lightpole.net:8402/travel-link/servlet/receive</tr3Url></TxnMsgContent></MasMessage>";
            //提交xml到网关，获取TR2返回的xml结果
            //msgReturn = new KuaiQianHelper().HttpPost(gatewayUrl,reqXml,merchantId,MerchantPw,prikey_path,prikey_password); //获取返回的TR2数据
            msgReturn = new KuaiQianHelper().HttpPost(gatewayUrl, reqXml.ToString(), MerchantId, MerchantPw, prikey_path, prikey_password); 

            ////如果有：xmlns去掉获取到的TR2数据中的xmlns属性，否则加载不到对象中
            if (msgReturn.IndexOf("xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\"") > 1)
            {
                msgReturn = msgReturn.Replace(" xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\"", "");
            }

            ////商家一定要添加日志，商家以自己的方式添加日志，以下写XML只做临时测试用
            ////******特别注意：以下部分为:将获取的TR2数据存入文件(xml\receive\),调试完要把该出代码删除，以免正式上线后生成很多垃圾文件，******************
            XmlDocument xmlResponsetr2 = new XmlDocument();
            xmlResponsetr2.LoadXml(msgReturn);
            XmlNode node = xmlResponsetr2.SelectSingleNode("MasMessage/TxnMsgContent/externalRefNumber");	//获取交易返回数据中的外部跟踪编号（externalRefNumber）
            string logPathtr2 = HttpContext.Current.Request.PhysicalApplicationPath + "xml\\receive\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_ErrorPUR.xml";
            if (node != null)
            {
                logPathtr2 = HttpContext.Current.Request.PhysicalApplicationPath + "xml\\receive\\" + node.InnerText.ToString() + "_TR2PURReceive.xml";
            }
            xmlResponsetr2.Save(logPathtr2);
            ////******写入文件结束******************

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(msgReturn);
            XmlNodeList list = xmlDoc.SelectNodes("//TxnMsgContent");// CardInfoContent节点放入列表	
            if (list.Count == 0)//判断TxnMsgContent有没有数据，有数据表示有记录返回，没有表示出错
            {
                this.pnlInfo.Visible = true;
                //获取错误信息
                string errorMessage = xmlDoc.SelectSingleNode("MasMessage/ErrorMsgContent/errorMessage").InnerText.ToString();
                this.lblInfo.Text = errorMessage; //显示错误信息
            }
            else
            {
                responseCode = xmlDoc.SelectSingleNode("MasMessage/TxnMsgContent/responseCode").InnerText.ToString();//获取应答码，如果要获取TxnMsgContent节点下其他节点数据，也用此方式
                try
                {
                    externalRefNumberback = xmlDoc.SelectSingleNode("MasMessage/TxnMsgContent/externalRefNumber").InnerText.ToString();//获取外部跟踪编号：商家订单号
                }
                catch
                {
                    externalRefNumberback = "";
                }
                try
                {
                refNumberback = xmlDoc.SelectSingleNode("MasMessage/TxnMsgContent/refNumber").InnerText.ToString();//获取系统参考号：快钱交易号
                }
                catch
                {
                    refNumberback = "";
                }
                try
                {
                    authorizationCodeback = xmlDoc.SelectSingleNode("MasMessage/TxnMsgContent/authorizationCode").InnerText.ToString();//获取授权码
                }
                catch //如果是非直线银行交易，会没有authorizationCodeback节点返回
                {
                    authorizationCodeback = "";
                }
                                                
                if (responseCode == "C0")//c0表示正在处理中
                {
                    this.pnlInfo.Visible = false;

                    KQHelper.mg = responseCode;//将应答码传给公共变量
                    string payurl = "show.aspx?mg=" + KQHelper.mg;
                    Response.Redirect(payurl);
                    Response.Write("<script language:javascript>javascript:window.opener=null;window.close();</script>");
                }
                if (responseCode == "00")//00表示交易成功，
                {

                    this.pnlInfo.Visible = true;
                    this.lblInfo.Text = "交易成功，外部跟踪编号(商家订单号)：" + externalRefNumberback + "|系统参考号(快钱交易号)：" + refNumberback + "|授权码：" + authorizationCodeback;           

                    //此处可插入商户逻辑处理，将订单信息更新数据库，

                    //如果是专线的交易因为会在同链路返回TR2所以可以在此处处理成功交易的数据，非直连银行的交易要在receive页面的TR4发送后做成功交易的数据处理
                }
                else//不是c0表示提交的支付信息有错误
                {
                    this.pnlInfo.Visible = true;
                    try//KuaiQianHelper.KuaiQianMsg 哈希应答码表的数据不全，如果返回的应答码不在哈希应答码表中则系统会报错
                    {
                        
                        this.lblInfo.Text = "应答码：" + responseCode + " 应答码标示：" + Msg.KuaiQianMsg[responseCode].ToString();//根据应答码获取应答消息文本
                    }
                    catch
                    {
                        this.lblInfo.Text = "交易出错，应答码：" + responseCode;
                    }
                }
            }

        }
        catch
        {
            ////商家一定要添加日志，商家以自己的方式添加日志，以下写XML只做临时测试用
            ////******特别注意：以下部分为:将获取的TR2数据存入文件(xml\receive\),调试完要把该出代码删除，以免正式上线后生成很多垃圾文件，******************
            XmlDocument xmlResponsetr2 = new XmlDocument();
            xmlResponsetr2.LoadXml(msgReturn);
            XmlNode node = xmlResponsetr2.SelectSingleNode("MasMessage/TxnMsgContent/externalRefNumber");	//获取查询返回数据中的外部跟踪编号（externalRefNumber）
            string logPathtr2 = HttpContext.Current.Request.PhysicalApplicationPath + "xml\\receive\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_ErrorPUR.xml";
            if (node != null)
            {
                logPathtr2 = HttpContext.Current.Request.PhysicalApplicationPath + "xml\\receive\\" + node.InnerText.ToString() + "_TR2PUR.xml";
            }
            xmlResponsetr2.Save(logPathtr2);
            ////******写入文件结束******************
            this.pnlInfo.Visible = true;
            this.lblInfo.Text = "系统异常，应答码：" + responseCode + "  其他异常：" + msgReturn;
        }
    }
    protected void btnBack_Click(object sender, EventArgs e)
    {
        Response.Redirect("index.aspx");
    }
    protected void btnClose_Click(object sender, EventArgs e)
    {
        Response.Write("<script language:javascript>javascript:window.opener=null;window.close();</script>");



    }
}
